use inkwell::{
    context::Context,
    targets::{CodeModel, InitializationConfig, RelocMode, Target, TargetTriple},
    OptimizationLevel,
};
use network_scanner_detector_compiler::{compile, LlvmIrStringTarget, LlvmModuleTarget};

static TEXT: &str = r"def match ether_payload(int[2]) {
    0x0800 => ipv4,
    0x0806 => arp,
    0x86DD => ipv6,
}

def chain main {
    def ext dst = [0:6];
    def ext src = [6:6];
    def ethertype = [12:2];
    
    let ext is_ether_v2 = ethertype >= 0x0800;
    if is_ether_v2 {
        let ext type = ethertype;
        jump ext [14:-0] match ether_payload(ethertype);
    } else {
        stop;
    }
}";

fn main() {
    Target::initialize_bpf(&InitializationConfig::default());
    let target_triple = TargetTriple::create("bpf-unknown-unknown");
    let target = Target::from_triple(&target_triple).unwrap();
    let target_machine = target
        .create_target_machine(
            &target_triple,
            "generic",
            "",
            OptimizationLevel::None,
            RelocMode::Default,
            CodeModel::Default,
        )
        .unwrap();
    let context = Context::create();
    let compile_target = LlvmModuleTarget::new(&context, &target_machine);
    let mut compile_target = LlvmIrStringTarget::new(&compile_target);
    //let mut compile_target = LlvmObjectTarget::new(&compile_target, "output.o");
    let ir_string = compile(&mut compile_target, TEXT, "ether").unwrap();
    println!("{}", ir_string);
}
